package com.xsjiong.jaript.utils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;

public final class JReflector {
	private static HashMap<String, Class> ClassCache = new HashMap<>();

	public static Class<?> getClassSafely(String name) {
		if (name == null) return null;
		Class<?> C = ClassCache.get(name);
		if (C == null)
			try {
				ClassCache.put(name, C = Class.forName(name));
			} catch (ClassNotFoundException e) {
				return null;
			}
		return C;
	}

	public static Class<?> getClass(String name) throws ClassNotFoundException {
		if (name == null) return null;
		Class<?> C = ClassCache.get(name);
		if (C == null)
			ClassCache.put(name, C = Class.forName(name));
		return C;
	}

	public static Object getMethodAndInvoke(Class<?> c, Object target, String name, Object... args) throws NoSuchMethodException {
		Class<?>[] arg = null;
		FindMethod:
		for (Method one : c.getMethods()) {
			if (!one.getName().equals(name)) continue;
			arg = one.getParameterTypes();
			// TODO 可变参数？
			if (arg.length != args.length) continue;
			for (int i = 0; i < arg.length; i++)
				if (!arg[i].isInstance(args[i])) continue FindMethod;
			try {
				return one.invoke(target, args);
			} catch (IllegalAccessException e) {
				e.printStackTrace();
				return null;
			} catch (InvocationTargetException e) {
				throw new RuntimeException(e.getTargetException());
			}
		}
		throw new NoSuchMethodException("Can't found method \"" + name + "\" in class \"" + c + "\"");
	}
	
	public static Object getMember(Class<?> cl, String name) {
		Class[] clz = cl.getClasses();
		for (int i=0;i < clz.length;i++)
			if (clz[i].getSimpleName().equals(name))
				return clz[i];
		try {
			return cl.getField(name);
		} catch (Throwable t) {}
		return null;
	}
}
